home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Drivers / Fd / Fd_reloc.tproj / Fd.m < prev    next >
Text File  |  1995-12-30  |  5KB  |  194 lines

  1. /*
  2.  * THIS SOFTWARE IS PROVIDED BY MARK SALYZYN ``AS IS'' AND ANY EXPRESS OR
  3.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  4.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  5.  * NO EVENT SHALL MARK SALYZYN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  6.  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
  8.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  9.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  11.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12.  *
  13.  *    @(#)Fd.m        1.1 (Salyzyn)    95/12/05
  14.  */
  15.  
  16. #import "Fd.h"
  17.  
  18. /*
  19.  *    A non-instantiated variable telling us which major number we are
  20.  *    using. We do not allow more than one instance of the FD driver.
  21.  */
  22. static int    FdMajor ;
  23.  
  24. @implementation Fd
  25.  
  26. #define Fdclose    nulldev
  27.  
  28. + (BOOL) probe : description
  29. {    Fd *            dev ;
  30.     IODirectDevice *    desc ;
  31.     char            Name[sizeof(FdDeviceName) + 1] ;
  32.     unsigned        instance ;
  33.     const char *        String ;
  34.     IOConfigTable *        config = [description configTable] ;
  35.     const char *        cp ;
  36.     static int        Fdopen(), Fdclose(), Fdread(), Fdwrite(),
  37.                 Fdioctl(), Fdselect() ;
  38.     extern            nodev(), nulldev() ;
  39.     extern char *        strcpy() ;
  40.  
  41.     /*
  42.      *    Find out what we have attached.
  43.      */
  44.     if ((dev = [self alloc]) == nil) {
  45.         IOLog ("%s: Failed to allocate an instance\n", FdDeviceName) ;
  46.         return NO ;
  47.     }
  48.  
  49.     strcpy (Name, FdDeviceName)[sizeof(Name) - 1] = '\0' ;
  50.     instance = 0 ;
  51.     if (String = [config valueForStringKey : "Instance"]) {
  52.         for (cp = String; ('0' <= *cp) && (*cp <= '9'); ++cp)
  53.             instance = (instance * 10) + *cp - '0' ;
  54.         [config freeString : String] ;
  55.     }
  56.     Name[sizeof(Name) - 2] = instance + '0' ;
  57.     [dev setName : Name] ;
  58.     [dev setDeviceKind : FdDeviceKind] ;
  59.     [dev setUnit : instance] ;
  60.     if (instance >= 1) {
  61.         [dev free] ;
  62.         IOLog ("%s Too many instances\n", [self name]) ;
  63.         return NO ;
  64.     }
  65.     if ((FdMajor = IOAddToCdevsw (
  66.         Fdopen,     /* IOSwitchFunc openFunc    */
  67.         Fdclose,     /* IOSwitchFunc closeFunc    */
  68.         Fdread,     /* IOSwitchFunc readFunc    */
  69.         Fdwrite,     /* IOSwitchFunc writeFunc    */
  70.         Fdioctl,     /* IOSwitchFunc ioctlFunc    */
  71.         nodev,     /* IOSwitchFunc stopFunc    */
  72.         nulldev,     /* IOSwitchFunc resetFunc    */
  73.         Fdselect,     /* IOSwitchFunc selectFunc    */
  74.         nodev,     /* IOSwitchFunc mmapFunc    */
  75.         nodev,     /* IOSwitchFunc getcFunc    */
  76.         nodev)     /* IOSwitchFunc putcFunc    */) == -1) {
  77.         [dev free] ;
  78.         IOLog ("%s failed to place into Cdevsw\n", [self name]) ;
  79.         return NO ;
  80.     }
  81.     [dev registerDevice] ;
  82.  
  83.     if ((desc = [dev initFromDeviceDescription : description]) == nil) {
  84.         IOLog ("%s: Failed to init Device Description\n",FdDeviceName) ;
  85.         [dev free] ;
  86.         return NO ;
  87.     }
  88.  
  89.     return YES ;
  90. }
  91.  
  92. /*
  93.  *    Name: getIntValues : values forParameter : parameter count : count
  94.  *    Handle providing information back to user routines. This is an
  95.  *    out-of-bound Kernel Server channel. We allow asking for the following:
  96.  *        IOMajorDevice    Major device of this instance of the driver
  97.  *        IONumberDevice    Number of ports handled on this instance.
  98.  */
  99. - (IOReturn) getIntValues : (unsigned *)values
  100.          forParameter : (IOParameterName) parameter
  101.             count : (unsigned *) count
  102. {    unsigned    maxCount = *count ;
  103.  
  104.     if (maxCount == 0)
  105.         maxCount = IO_MAX_PARAMETER_ARRAY_LENGTH ;
  106.  
  107.     if (strcmp(parameter, "IOMajorDevice") == 0) {
  108.         values[0] = FdMajor ;
  109.         *count = 1 ;
  110.         return IO_R_SUCCESS ;
  111.     }
  112.  
  113.     if (strcmp (parameter, "IONumberDevice") == 0) {
  114.         values[0] = NOFILE ;
  115.         *count = 1 ;
  116.         return IO_R_SUCCESS ;
  117.     }
  118.  
  119.     return [super getIntValues : values
  120.               forParameter : parameter
  121.                  count : &maxCount] ;
  122. }
  123.  
  124. /* ARGSUSED */
  125. static int
  126. Fdopen (dev_t dev, int flag, int mode)
  127. {    struct file *    fp ;
  128.     struct file *    dfp ;
  129.  
  130.     /*
  131.      *    Find the file pointers for the file descriptors, both
  132.      *    must be valid.
  133.      */
  134.     if (((fp = getf (u.u_r.r_val1)) == NULL)
  135.      || ((dfp = getf (minor (dev))) == NULL)
  136.      || (fp == dfp))
  137.         return (EBADF) ;
  138.     /*
  139.      *    Make sure opened up in same mode
  140.      */
  141.     if (((flag & (FREAD | FWRITE)) | dfp->f_flag) != dfp->f_flag)
  142.         return (EACCES) ;
  143.  
  144.     return (0) ;
  145. }
  146.  
  147. static int
  148. Fdread (dev_t dev, struct uio *uio, int flag)
  149. {
  150.     if (u.u_ap[0] == minor (dev))
  151.         return (EBADF) ;
  152.     u.u_ap[0] = minor (dev) ;
  153.     /*
  154.      *    Ok, so this is MACH specific, saves us some stack
  155.      *    space though!
  156.      */
  157.     rwuio (uio, UIO_READ) ;
  158.     return (u.u_error) ;
  159. }
  160.  
  161. static int
  162. Fdwrite (dev_t dev, struct uio *uio, int flag)
  163. {
  164.     if (u.u_ap[0] == minor (dev))
  165.         return (EBADF) ;
  166.     u.u_ap[0] = minor (dev) ;
  167.     rwuio (uio, UIO_WRITE) ;
  168.     return (u.u_error) ;
  169. }
  170.  
  171. static int
  172. Fdioctl (dev_t dev, int cmd, caddr_t data, int flag)
  173. {
  174.     if (u.u_ap[0] == minor (dev))
  175.         return (EBADF) ;
  176.     u.u_ap[0] = minor (dev) ;
  177.     ioctl () ;
  178.     return (u.u_error) ;
  179. }
  180.  
  181. static int
  182. Fdselect (dev_t dev, int rw)
  183. {
  184.     struct file *    fp ;
  185.  
  186.     if (((fp = getf (minor(dev))) == NULL)
  187.      || (fp->f_ops == NULL)
  188.      || (fp->f_ops->fo_select == NULL))
  189.         return (1) ;
  190.     return ((*fp->f_ops->fo_select)(fp, rw)) ;
  191. }
  192.  
  193. @end
  194.